package com.tourscool.springboot.starter.redisson;

import com.tourscool.springboot.starter.redisson.config.ClusterServersConfig;
import com.tourscool.springboot.starter.redisson.config.ConfigType;
import com.tourscool.springboot.starter.redisson.config.SingleServerConfig;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.redisson.config.TransportMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 我长得帅，不需要注释
 *
 * @author Carlton
 * @date 2018/8/22
 */
@Configuration
@EnableConfigurationProperties(value = RedissonProperties.class)
public class RedissonConfigConfigure {
    @Autowired
    private RedissonProperties mRedissonProperties;

    private void singleConfig(final Config config) {
        final SingleServerConfig singleServerConfig = mRedissonProperties.getSingle();
        config.useSingleServer()
                .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
                .setPingConnectionInterval(singleServerConfig.getPingConnectionInterval())
                .setConnectTimeout(singleServerConfig.getConnectTimeout())
                .setTimeout(singleServerConfig.getTimeout())
                .setRetryAttempts(singleServerConfig.getRetryAttempts())
                .setRetryInterval(singleServerConfig.getRetryInterval())
                .setPassword(singleServerConfig.getPassword())
                .setSubscriptionsPerConnection(singleServerConfig.getSubscriptionsPerConnection())
                .setClientName(singleServerConfig.getClientName())
                .setAddress(singleServerConfig.getAddress())
                .setKeepAlive(singleServerConfig.isKeepAlive())
                .setTcpNoDelay(singleServerConfig.isTcpNoDelay())
                .setSubscriptionConnectionMinimumIdleSize(singleServerConfig.getSubscriptionConnectionMinimumIdleSize())
                .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
                .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
                .setDatabase(singleServerConfig.getDatabase())
                .setDnsMonitoringInterval(singleServerConfig.getDnsMonitoringInterval());
    }

    private void clusterConfig(final Config config) {
        final ClusterServersConfig clusterServersConfig = mRedissonProperties.getCluster();
        config.useClusterServers()
                .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
                .setPingConnectionInterval(clusterServersConfig.getPingConnectionInterval())
                .setConnectTimeout(clusterServersConfig.getConnectTimeout())
                .setTimeout(clusterServersConfig.getTimeout())
                .setRetryAttempts(clusterServersConfig.getRetryAttempts())
                .setRetryInterval(clusterServersConfig.getRetryInterval())
                .setPassword(clusterServersConfig.getPassword())
                .setSubscriptionsPerConnection(clusterServersConfig.getSubscriptionsPerConnection())
                .setClientName(clusterServersConfig.getClientName())
                .addNodeAddress(clusterServersConfig.getNodeAddresses().toArray(new String[0]))
                .setScanInterval(clusterServersConfig.getScanInterval())
                .setKeepAlive(clusterServersConfig.isKeepAlive())
                .setTcpNoDelay(clusterServersConfig.isTcpNoDelay())
                .setSubscriptionConnectionMinimumIdleSize(clusterServersConfig.getSubscriptionConnectionMinimumIdleSize())
                .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
                .setDnsMonitoringInterval(clusterServersConfig.getDnsMonitoringInterval());
    }

    @Bean(destroyMethod = "shutdown")
    public RedissonClient redisson() {
        final Config config = new Config();
        final ConfigType configType = ConfigType.valueOf(mRedissonProperties.getType());
        if (ConfigType.SINGLE.equals(configType)) {
            singleConfig(config);
        } else if (ConfigType.CLUSTER.equals(configType)) {
            clusterConfig(config);
        } else {
            throw new RuntimeException("Redisson没有找到配置类型:" + mRedissonProperties.getType());
        }
        if (mRedissonProperties.getThreads() != null) {
            config.setThreads(mRedissonProperties.getThreads());
        }
        if (mRedissonProperties.getNettyThreads() != null) {
            config.setNettyThreads(mRedissonProperties.getNettyThreads());
        }
        config.setCodec(new JsonJacksonCodec());
        config.setTransportMode(TransportMode.NIO);
        return Redisson.create(config);
    }
}
